home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / c / cug236.zip / BAWKDO.C < prev    next >
Text File  |  1980-01-02  |  13KB  |  782 lines

  1. /*
  2.     HEADER:        CUG000.00;
  3.     TITLE:        BAWK Actions Interpreter;
  4.     DATE:        05/17/1987;
  5.     VERSION:    1.1;
  6.     FILENAME:    BAWKDO.C;
  7.     SEE-ALSO:    BAWK.C;
  8.     AUTHORS:    W. C. Colley III, B. Brodt;
  9. */
  10.  
  11. /*
  12.  * Bawk C actions interpreter
  13.  */
  14. #include <stdio.h>
  15. #include "bawk.h"
  16.  
  17. /* Functions local to this module.    */
  18.  
  19. void expr1(), expr2(), expr3(), expr4(), expr5(), expr6(), expr7(), expr8();
  20. void expr9(), expr10(), postincdec(), preincdec(), primary(), skip();
  21. void skipstatement(), statement();
  22.  
  23. int dopattern( pat )
  24. char *pat;
  25. {
  26.     Where = PATTERN;
  27.     Actptr = pat;
  28.     getoken();
  29.     expression();
  30.     return popint();
  31. }
  32.  
  33. void doaction( act )
  34. char *act;
  35. {
  36.     Where = ACTION;
  37.     Actptr = act;
  38.     getoken();
  39.     while ( Token!=T_EOF )
  40.         statement();
  41. }
  42.  
  43. void expression()
  44. {
  45.     expr1();
  46.     if ( Token==T_ASSIGN ) {
  47.         getoken();  expression();  assignment();
  48.     }
  49. }
  50.  
  51. void expr1()
  52. {
  53.     int ival;
  54.  
  55.     expr2();
  56.     for ( ;; )
  57.     {
  58.         if ( Token==T_LIOR )
  59.         {
  60.             getoken();
  61.             ival = popint();
  62.             expr2();
  63.             pushint( popint() || ival );
  64.         }
  65.         else
  66.             return;
  67.     }
  68. }
  69.  
  70. void expr2()
  71. {
  72.     int ival;
  73.  
  74.     expr3();
  75.     for ( ;; )
  76.     {
  77.         if ( Token==T_LAND )
  78.         {
  79.             getoken();
  80.             ival = popint();
  81.             expr3();
  82.             pushint( popint() && ival );
  83.         }
  84.         else
  85.             return;
  86.     }
  87. }
  88.  
  89. void expr3()
  90. {
  91.     int ival;
  92.  
  93.     expr4();
  94.     for ( ;; )
  95.     {
  96.         if ( Token==T_IOR )
  97.         {
  98.             getoken();
  99.             ival = popint();
  100.             expr4();
  101.             pushint( popint() | ival );
  102.         }
  103.         else
  104.             return;
  105.     }
  106. }
  107.  
  108.  
  109. void expr4()
  110. {
  111.     int ival;
  112.  
  113.     expr5();
  114.     for ( ;; )
  115.     {
  116.         if ( Token==T_AND )
  117.         {
  118.             getoken();
  119.             ival = popint();
  120.             expr5();
  121.             pushint( popint() & ival );
  122.         }
  123.         else
  124.             return;
  125.     }
  126. }
  127.  
  128. void expr5()
  129. {
  130.     int ival;
  131.  
  132.     expr6();
  133.     for ( ;; )
  134.     {
  135.         if ( Token==T_XOR )
  136.         {
  137.             getoken();
  138.             ival = popint();
  139.             expr6();
  140.             pushint( popint() ^ ival );
  141.         }
  142.         else
  143.             return;
  144.     }
  145. }
  146.  
  147. void expr6()
  148. {
  149.     int ival;
  150.  
  151.     expr7();
  152.     for ( ;; )
  153.     {
  154.         if ( Token==T_EQ )
  155.         {
  156.             getoken();
  157.             ival = popint();
  158.             expr7();
  159.             pushint( ival == popint() );
  160.         }
  161.         else if ( Token==T_NE )
  162.         {
  163.             getoken();
  164.             ival = popint();
  165.             expr7();
  166.             pushint( ival != popint() );
  167.         }
  168.         else
  169.             return;
  170.     }
  171. }
  172.  
  173. void expr7()
  174. {
  175.     int ival;
  176.  
  177.     expr8();
  178.     for ( ;; )
  179.     {
  180.         if ( Token==T_LE )
  181.         {
  182.             getoken();
  183.             ival = popint();
  184.             expr8();
  185.             pushint( ival <= popint() );
  186.         }
  187.         else if ( Token==T_GE )
  188.         {
  189.             getoken();
  190.             ival = popint();
  191.             expr8();
  192.             pushint( ival >= popint() );
  193.         }
  194.         else if ( Token==T_LT )
  195.         {
  196.             getoken();
  197.             ival = popint();
  198.             expr8();
  199.             pushint( ival < popint() );
  200.         }
  201.         else if ( Token==T_GT )
  202.         {
  203.             getoken();
  204.             ival = popint();
  205.             expr8();
  206.             pushint( ival > popint() );
  207.         }
  208.         else
  209.             return;
  210.     }
  211. }
  212.  
  213. void expr8()
  214. {
  215.     int ival;
  216.  
  217.     expr9();
  218.     for ( ;; )
  219.     {
  220.         if ( Token==T_SHL )
  221.         {
  222.             getoken();
  223.             ival = popint();
  224.             expr9();
  225.             pushint( ival << popint() );
  226.         }
  227.         else if ( Token==T_SHR )
  228.         {
  229.             getoken();
  230.             ival = popint();
  231.             expr9();
  232.             pushint( ival >> popint() );
  233.         }
  234.         else
  235.             return;
  236.     }
  237. }
  238.  
  239. void expr9()
  240. {
  241.     int ival;
  242.  
  243.     expr10();
  244.     for ( ;; )
  245.     {
  246.         if ( Token==T_ADD )
  247.         {
  248.             getoken();
  249.             ival = popint();
  250.             expr10();
  251.             pushint( ival + popint() );
  252.         }
  253.         else if ( Token==T_SUB )
  254.         {
  255.             getoken();
  256.             ival = popint();
  257.             expr10();
  258.             pushint( ival - popint() );
  259.         }
  260.         else
  261.             return;
  262.     }
  263. }
  264.  
  265. void expr10()
  266. {
  267.     int ival;
  268.  
  269.     primary();
  270.     for ( ;; )
  271.     {
  272.         if ( Token==T_MUL )
  273.         {
  274.             getoken();
  275.             ival = popint();
  276.             primary();
  277.             pushint( ival * popint() );
  278.         }
  279.         else if ( Token==T_DIV )
  280.         {
  281.             getoken();
  282.             ival = popint();
  283.             primary();
  284.             pushint( ival / popint() );
  285.         }
  286.         else if ( Token==T_MOD )
  287.         {
  288.             getoken();
  289.             ival = popint();
  290.             primary();
  291.             pushint( ival % popint() );
  292.         }
  293.         else
  294.             return;
  295.     }
  296. }
  297.  
  298. void primary()
  299. {
  300.     int index;
  301.     DATUM data;
  302.     VARIABLE *pvar;
  303.  
  304.     switch ( Token )
  305.     {
  306.     case T_LPAREN:
  307.         /*
  308.          * it's a parenthesized expression
  309.          */
  310.         getoken();
  311.         expression();
  312.         if ( Token!=T_RPAREN )
  313.             error( "missing ')'", ACT_ERROR );
  314.         getoken();
  315.         break;
  316.     case T_LNOT:
  317.         getoken();
  318.         primary();
  319.         pushint( ! popint() );
  320.         break;
  321.     case T_NOT:
  322.         getoken();
  323.         primary();
  324.         pushint( ~ popint() );
  325.         break;
  326.     case T_ADD:
  327.         getoken();
  328.         primary();
  329.         break;
  330.     case T_SUB:
  331.         getoken();
  332.         primary();
  333.         pushint( - popint() );
  334.         break;
  335.     case T_INCR:
  336.     case T_DECR:
  337.         preincdec();
  338.         break;
  339.     case T_MUL:
  340.         getoken();
  341.         primary();
  342.         /*
  343.          * If item on stack is an LVALUE, do an extra level of
  344.          * indirection before changing it to an LVALUE.
  345.          */
  346.         if ( Stackptr->lvalue )
  347.             Stackptr->value.dptr = *Stackptr->value.ptrptr;
  348.         Stackptr->lvalue = 1;
  349.         --Stackptr->class;
  350.         break;
  351.     case T_AND:
  352.         getoken();
  353.         primary();
  354.         if ( Stackptr->lvalue )
  355.             Stackptr->lvalue = 0;
  356.         else
  357.             error( "'&' operator needs an lvalue", ACT_ERROR );
  358.         break;
  359.     case T_CONSTANT:
  360.         pushint( Value.ival );
  361.         getoken();
  362.         break;
  363.     case T_REGEXP:
  364.         /*
  365.          * It's a regular expression - parse it and compile it.
  366.          */
  367.         if ( Where == PATTERN )
  368.         {
  369.             /*
  370.              * We're processing a pattern right now - perform a
  371.              * match of the regular expression agains input line.
  372.              */
  373.             unparse( Fields, Fieldcount, Linebuf, Fldsep );
  374.             pushint( match( Linebuf, Value.dptr ) );
  375.         }
  376.         else
  377.             push( 1, ACTUAL, BYTE, &Value );
  378.         getoken();
  379.         break;
  380.     case T_NF:
  381.         pushint( Fieldcount );
  382.         getoken();
  383.         break;
  384.     case T_NR:
  385.         pushint( Recordcount );
  386.         getoken();
  387.         break;
  388.     case T_FS:
  389.         Fldsep[1] = 0;
  390.         data.dptr = Fldsep;
  391.         push( 0, LVALUE, BYTE, &data );
  392.         getoken();
  393.         break;
  394.     case T_RS:
  395.         Rcrdsep[1] = 0;
  396.         data.dptr = Rcrdsep;
  397.         push( 0, LVALUE, BYTE, &data );
  398.         getoken();
  399.         break;
  400.     case T_FILENAME:
  401.         data.dptr = Filename;
  402.         push( 1, ACTUAL, BYTE, &data );
  403.         getoken();
  404.         break;
  405.     case T_DOLLAR:
  406.         /*
  407.          * It's a reference to one (or all) of the words in Linebuf.
  408.          */
  409.         getoken();
  410.         primary();
  411.         if ( index = popint() )
  412.         {
  413.             if ( index > Fieldcount )
  414.                 index = Fieldcount;
  415.             else if ( index < 1 )
  416.                 index = 1;
  417.             data.dptr = Fields[ index-1 ];
  418.         }
  419.         else
  420.         {
  421.             /*
  422.              * Reconstitute the line buffer in case any of the
  423.              * fields have been changed.
  424.              */
  425.             unparse( Fields, Fieldcount, Linebuf, Fldsep );
  426.             data.dptr = Linebuf;
  427.         }
  428.         /*
  429.          * $<expr>'s are treated the same as string constants:
  430.          */
  431.         push( 1, ACTUAL, BYTE, &data );
  432.         break;
  433.     case T_STRING:
  434.         push( 1, ACTUAL, BYTE, &Value );
  435.         getoken();
  436.         break;
  437.     case T_FUNCTION:
  438.         /*
  439.          * Do a built-in function call
  440.          */
  441.         index = Value.ival;
  442.         getoken();
  443.         function( index );
  444.         break;
  445.     case T_VARIABLE:
  446.         pvar = (VARIABLE *)Value.dptr;
  447.         getoken();
  448.         /*
  449.          * it's a plain variable. The way a variable is
  450.          * represented on the stack depends on its type:
  451.          *    lvalue class value.dptr
  452.          * vars:  1     0   address of var
  453.          * ptrs:  1     1   address of ptr to var
  454.          * array: 0     1   address of var
  455.          */
  456.         if ( pvar->vclass && !pvar->vlen )
  457.             /* it's a pointer */
  458.             data.ptrptr = &pvar->vptr;
  459.         else
  460.             /* an array or simple variable */
  461.             data.dptr = pvar->vptr;
  462.         /*
  463.          * If it's an array it can't be used as an LVALUE.
  464.          */
  465.         push( pvar->vclass, !pvar->vlen, pvar->vsize, &data );
  466.         break;
  467.     case T_EOF:
  468.         break;
  469.     default:
  470.         syntaxerror();
  471.     }
  472.     /*
  473.      * a "[" means it's an array reference
  474.      */
  475.     if ( Token==T_LBRACKET )
  476.     {
  477.         getoken();
  478.         if ( ! Stackptr->class )
  479.             error( "'[]' needs an array or pointer", ACT_ERROR );
  480.         /*
  481.          * compute the subscript
  482.          */
  483.         expression();
  484.         if ( Token!=T_RBRACKET )
  485.             error( "missing ']'", ACT_ERROR );
  486.         getoken();
  487.         index = popint();
  488.         /*
  489.          * compute the offset (subscript times two for int arrays)
  490.          * and then the effective address.
  491.          */
  492.         index *= Stackptr->size;
  493.         if ( Stackptr->lvalue )
  494.             /*
  495.              * It's a pointer - don't forget that the stack top
  496.              * item's value is the address of the pointer so we
  497.              * must do another level of indirection.
  498.              */
  499.             Stackptr->value.dptr =
  500.                 *(Stackptr->value.ptrptr) + index;
  501.         else
  502.             /*
  503.              * It's a plain array - the stac